package com.sdkj.fixed.asset.assets.service;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.sdkj.fixed.asset.api.assets.in_vo.*;
import com.sdkj.fixed.asset.api.assets.out_vo.*;
import com.sdkj.fixed.asset.api.login.out_vo.CompanyBaseListResult;
import com.sdkj.fixed.asset.api.login.pojo.LoginRole;
import com.sdkj.fixed.asset.api.login.pojo.LoginUser;
import com.sdkj.fixed.asset.assets.mapper.*;
import com.sdkj.fixed.asset.assets.util.*;
import com.sdkj.fixed.asset.common.base.BaseMapper;
import com.sdkj.fixed.asset.common.base.BaseService;
import com.sdkj.fixed.asset.common.base.PageParams;
import com.sdkj.fixed.asset.common.exception.LogicException;
import com.sdkj.fixed.asset.common.utils.JpushClientUtil;
import com.sdkj.fixed.asset.common.utils.TimeTool;
import com.sdkj.fixed.asset.pojo.assets.*;
import com.sdkj.fixed.asset.pojo.system.PushManagement;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @Author zhangjinfei
 * @Description //TODO 资产退库
 * @Date 2020/7/21 10:54
 */
@Service
public class WithdrawalService extends BaseService<Withdrawal> {
    private final static String TABLE_NAME="as_asset_withdrawal";
    private final static String COLUMN_NAME="withdrawal_id";

    private  final Logger log = LoggerFactory.getLogger(CollectService.class);

    @Resource
    private WithdrawalMapper mapper;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private CacheUtils cacheUtils;
    @Autowired
    private WarehouseService warehouseService;
    @Resource
    private AssetWithdrawalMapper assetWithdrawalMapper;
    @Resource
    private AssetLogMapper assetLogMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SetService setService;
    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private WarehouseMapper warehouseMapper;
    @Autowired
    private StandModelMapper standModelMapper;
    @Autowired
    private WarehouseHistoryMapper historyMapper;
    @Autowired
    private PushManagementMapper pushMapper;


    @Override
    public BaseMapper getMapper() {
        return mapper;
    }

    public List<WithdrawalResult> queryPages(PageParams<SearchNameParam> params){
        //--------- 权限 start
        String token = request.getHeader("token");
        // redis 查询用户权限： 如果是管理员为false 查询全部
        LoginUser loginUser = cacheUtils.getUser(token);
        String userId = loginUser.getUserId();
        List<LoginRole> loginRoles = loginUser.getLoginRoles();
        List<String> roles = loginRoles.stream().map(LoginRole::getRoleLevel).collect(Collectors.toList());
        List<CompanyBaseListResult> companys = loginUser.getCompanys();
        String orgId = companys.get(0).getCompanyId();
        Integer isAllData = reportMapper.selectUserIsAllDataAuth(userId);
        if(isAllData==1){
            userId = null;
        }
        PageHelper.startPage(params.getCurrentPage(),params.getPerPageTotal());
        SearchNameParam param = params.getParams();
        List<WithdrawalResult> list = mapper.queryPages(param.getSearchName(),orgId,userId);
        list.stream().forEach(e->{
            String withdrawalId = e.getWithdrawalId();
            List<WarehouseHistoryResult> warehouseList = historyMapper.queryWarehouseHistory(withdrawalId,2);
            e.setWarehouseList(warehouseList);
        });
        return list;
    }
    /**
     * 主键ID 查询 结果集
     * @param withdrawalId
     * @return
     */
    public WithdrawalResult queryWithdrawal(String withdrawalId) {
        WithdrawalResult result = mapper.selectByWithdrawalId(withdrawalId);
        List<WarehouseHistoryResult> warehouseList = historyMapper.queryWarehouseHistory(withdrawalId,2);
        result.setWarehouseList(warehouseList);
        return result;
    }

    public Integer insertWithdrawal(WithdrawalParam withdrawal) {
        //--------- 权限 start
        String token = request.getHeader("token");
        // redis 查询用户权限： 如果是管理员为false 查询全部
        LoginUser loginUser = cacheUtils.getUser(token);
        String userId = loginUser.getUserId();
        List<CompanyBaseListResult> companys = loginUser.getCompanys();
        String orgId = companys.get(0).getCompanyId();
        Long increment = redisUtil.getIncr("LY_"+orgId+"_"+DateTools.nowDayStr(),DateTools.expiresTime());
        String no = String.format("%04d",Long.valueOf(increment));

        withdrawal.setWithdrawalNo("TK"+DateTools.nowDayStr()+no);
        withdrawal.setState(1); // 未签字
        withdrawal.setApproval(2); // 已审批
        withdrawal.setWithdrawalType(0); // 管理员发放
        withdrawal.setOrgId(orgId);
        withdrawal.setCreateTime(DateTools.nowDate());
        withdrawal.setCreateUser(userId);
        withdrawal.setUpdateTime(DateTools.nowDate());
        withdrawal.setUpdateUser(userId);
        withdrawal.setIsDelete(0);

        int i = mapper.insertSelective(withdrawal);
        List<String> assetIdList = withdrawal.getAssetIdList();
        for (String assetId:assetIdList) {
            AssetWithdrawal assetWithdrawal = new AssetWithdrawal();
            assetWithdrawal.setWithdrawalId(withdrawal.getWithdrawalId());
            assetWithdrawal.setAssetId(assetId);
            assetWithdrawal.setIsDeleted(0);
            assetWithdrawal.setType(1);
            assetWithdrawal.setCreateUser(userId);
            assetWithdrawal.setCreateDate(TimeTool.getCurrentTimeStr());
            assetWithdrawal.setUpdateUser(userId);
            assetWithdrawal.setUpdateDate(TimeTool.getCurrentTimeStr());
            assetWithdrawalMapper.insertSelective(assetWithdrawal);
        }
        historyMapper.batchInsert(assetIdList ,withdrawal.getWithdrawalId(),2);
        warehouseService.updateAssetState(assetIdList, "退库中",null,null);
        // 添加日志
        insertLog(withdrawal);

        //推送消息给退库人
        String[] asia = {withdrawal.getWithdrawalUserId()};
        String notification_title = "资产退库";
        String msg_title = "资产退库";
        String msg_content = "资产退库，单号【"+ withdrawal.getWithdrawalNo() +"】请签字";
        log.info("资产退库,消息推送人："+ JSONObject.toJSONString(asia));
        JpushClientUtil.sendToAsia(asia, notification_title, msg_title, msg_content,"");

        String finalMsg_content = msg_content;
        Arrays.stream(asia).forEach(e->{
            PushManagement pu = new PushManagement();
            pu.setCompanyId(orgId);
            pu.setContent(finalMsg_content);
            pu.setCtime(DateTools.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
            pu.setCuser(userId);
            pu.setSender(e);
            pu.setResult(0);
            pushMapper.insertSelective(pu);
        });

        return i;
    }
    private void insertLog(WithdrawalParam withdrawal) {
        String token = request.getHeader("token");
        // redis 查询用户权限： 如果是管理员为false 查询全部
        LoginUser loginUser = cacheUtils.getUser(token);
        String userId = loginUser.getUserId();
        String userName = loginUser.getUserName();
        List<String> assetIdList = withdrawal.getAssetIdList();
        for (String assetId:assetIdList) {
            AssetLog assetLog = new AssetLog();
            assetLog.setCreateTime(DateTools.nowDate());
            assetLog.setCreateUser(userId);
            assetLog.setUpdateTime(DateTools.nowDate());
            assetLog.setUpdateUser(userId);
            assetLog.setLogType("退库");

            WarehouseResult warehouseResult = warehouseService.queryByAssetId(assetId);
            assetLog.setAssetId(assetId);
            assetLog.setHandlerUser(userName);
            assetLog.setHandlerId(withdrawal.getWithdrawalId());
            LogContext context  =  new LogContext();
            context.setModelName("退库");
            context.setBeforeName(warehouseResult.getHandlerUser());
            context.setAfterName("<空>");
            context.setBeforeState("在用");
            context.setAfterState("退库中");
            assetLog.setHandlerContext(ChangLogUtil.simpleLogContxt(context));
            assetLogMapper.insertSelective(assetLog);
        }
    }
    private void insertLog2(List<String> assetIdList,String id) {
        String token = request.getHeader("token");
        LoginUser loginUser = cacheUtils.getUser(token);
        String userId = loginUser.getUserId();
        String userName = loginUser.getUserName();
        for (String assetId:assetIdList) {
            AssetLog assetLog = new AssetLog();
            assetLog.setCreateTime(DateTools.nowDate());
            assetLog.setCreateUser(userId);
            assetLog.setUpdateTime(DateTools.nowDate());
            assetLog.setUpdateUser(userId);
            assetLog.setLogType("退库");
            WarehouseResult warehouseResult = warehouseService.queryByAssetId(assetId);
            assetLog.setAssetId(assetId);
            assetLog.setHandlerUser(userName);
            assetLog.setHandlerId(id);
            assetLog.setHandlerContext("用户["+userName+"]已签字成功");
            assetLogMapper.insertSelective(assetLog);
        }
    }
    // 删除日志
    private void delLog(List<String> assetIdList, String handlerId) {
        //--------- 权限 start
        String token = request.getHeader("token");
        LoginUser loginUser = cacheUtils.getUser(token);
        String userId = loginUser.getUserId();
        String userName = loginUser.getUserName();

        for (String assetId:assetIdList) {
            AssetLog assetLog = new AssetLog();
            assetLog.setCreateTime(DateTools.nowDate());
            assetLog.setCreateUser(userId);
            assetLog.setUpdateTime(DateTools.nowDate());
            assetLog.setUpdateUser(userId);
            assetLog.setLogType("退库");
            assetLog.setAssetId(assetId);
            assetLog.setHandlerUser(userName);
            assetLog.setHandlerContext("管理员" + userName + "将修改或删除退库单");
            assetLogMapper.insertSelective(assetLog);
        }
    }
    /**
     * 修改
     * @param withdrawal
     * @return
     */
    public Integer updateWithdrawal(WithdrawalParam withdrawal) {
        String token = request.getHeader("token");
        String orgId = request.getHeader("orgId");
        LoginUser loginUser = cacheUtils.getUser(token);
        String userId = loginUser.getUserId();

        withdrawal.setUpdateTime(DateTools.nowDate());
        withdrawal.setUpdateUser(userId);

        //删除之前的资产，重新插入
        Example example = new Example(AssetWithdrawal.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("withdrawalId", withdrawal.getWithdrawalId());
        List<AssetWithdrawal> assetWithdrawals = assetWithdrawalMapper.selectByExample(example);
        assetWithdrawalMapper.deleteByExample(example);

        List<String> delAssetIdList = assetWithdrawals.stream().map(e -> e.getAssetId()).collect(Collectors.toList());
        // 恢复数据
        warehouseService.updateAssetState(delAssetIdList, "在用",null,null);

        Example example2 = new Example(WarehouseHistory.class);
        Example.Criteria criteria2 = example2.createCriteria();
        criteria2.andEqualTo("handerId", withdrawal.getWithdrawalId());
        criteria2.andEqualTo("handerType", 2);
        historyMapper.deleteByExample(example2);
        // 删除日志
        delLog(delAssetIdList, withdrawal.getWithdrawalId());

        int i = mapper.updateByPrimaryKeySelective(withdrawal);
        List<String> assetIdListBefore = queryWithdrawal(withdrawal.getWithdrawalId())
                .getWarehouseList().stream()
                .map(e -> e.getAssetId())
                .collect(Collectors.toList());

        List<String> assetIdList = withdrawal.getAssetIdList();
        //新增
        for (String assetId : assetIdList) {
            AssetWithdrawal assetWithdrawal = new AssetWithdrawal();
            assetWithdrawal.setWithdrawalId(withdrawal.getWithdrawalId());
            assetWithdrawal.setAssetId(assetId);
            assetWithdrawal.setType(1);
            assetWithdrawal.setIsDeleted(0);
            assetWithdrawal.setCreateUser(userId);
            assetWithdrawal.setCreateDate(TimeTool.getCurrentTimeStr());
            assetWithdrawal.setUpdateUser(userId);
            assetWithdrawal.setUpdateDate(TimeTool.getCurrentTimeStr());
            assetWithdrawalMapper.insertSelective(assetWithdrawal);
        }
        historyMapper.batchInsert(assetIdList ,withdrawal.getWithdrawalId(),2);
        warehouseService.updateAssetState(assetIdList, "退库中",null,null);
        // 添加日志
        insertLog(withdrawal);

        Withdrawal withdrawal1 = mapper.selectByPrimaryKey(withdrawal.getWithdrawalId());
        //推送消息给退库人
        String[] asia = {withdrawal1.getWithdrawalUserId()};
        String notification_title = "资产退库";
        String msg_title = "资产退库";
        String msg_content = "资产退库，单号【"+ withdrawal1.getWithdrawalNo() +"】请签字";
        log.info("资产退库,消息推送人："+ JSONObject.toJSONString(asia));
        JpushClientUtil.sendToAsia(asia, notification_title, msg_title, msg_content,"");

        String finalMsg_content = msg_content;
        Arrays.stream(asia).forEach(e->{
            PushManagement pu = new PushManagement();
            pu.setCompanyId(orgId);
            pu.setContent(finalMsg_content);
            pu.setCtime(DateTools.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
            pu.setCuser(userId);
            pu.setSender(e);
            pu.setResult(0);
            pushMapper.insertSelective(pu);
        });

        return i;
    }
    public Integer deleteWithdrawal(String withdrawalId) {
        // 删除主表
        int i = mapper.deleteByPrimaryKey(withdrawalId);
        //删除关联表
        Example example = new Example(AssetWithdrawal.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("withdrawalId", withdrawalId);
        List<AssetWithdrawal> assetWithdrawalList = assetWithdrawalMapper.selectByExample(example);
        List<String> assetIdList = assetWithdrawalList.stream().map(e -> {
            return e.getAssetId();
        }).collect(Collectors.toList());
        assetWithdrawalMapper.deleteByExample(example);
//        删除历史记录
        Example example2 = new Example(WarehouseHistory.class);
        Example.Criteria criteria2 = example2.createCriteria();
        criteria2.andEqualTo("handerId", withdrawalId);
        criteria2.andEqualTo("handerType", 2);
        historyMapper.deleteByExample(example2);
        warehouseService.updateAssetState(assetIdList, "在用",null,null);
        // 删除日志
        delLog(assetIdList,withdrawalId);
        return i;
    }

    public List<WithdrawalExport> queryAll( String token,String searchName) {
        LoginUser loginUser = cacheUtils.getUser(token);
        String userId = loginUser.getUserId();
        List<LoginRole> loginRoles = loginUser.getLoginRoles();
        List<String> roles = loginRoles.stream().map(LoginRole::getRoleLevel).collect(Collectors.toList());
        List<CompanyBaseListResult> companys = loginUser.getCompanys();
        String orgId = companys.get(0).getCompanyId();
        Integer isAllData = reportMapper.selectUserIsAllDataAuth(userId);
        if(isAllData==1){
            userId = null;
        }
        List<WithdrawalExport> listWithdrawalExport = new ArrayList<>();

        List<WithdrawalResult> list = mapper.queryPages(searchName,orgId,userId);
        list.stream().forEach(e->{
            String withdrawalId = e.getWithdrawalId();
            List<WarehouseHistoryResult> warehouseList = historyMapper.queryWarehouseHistory(withdrawalId,2);
            e.setWarehouseList(warehouseList);
            WithdrawalExport withdrawalExport = new WithdrawalExport();
            BeanUtils.copyProperties(e,withdrawalExport);

            List<WarehouseBase> listBase = new ArrayList<>();
            warehouseList.stream().forEach(w->{
                WarehouseBase base = new WarehouseBase();
                BeanUtils.copyProperties(w,base);
                listBase.add(base);
            });
            withdrawalExport.setList(listBase);
            listWithdrawalExport.add(withdrawalExport);
        });
        return listWithdrawalExport;
    }


    public Workbook printWithdrawal(List<String> withdrawalList){
        HSSFWorkbook wb=new HSSFWorkbook();
        String title = "资产退库单";
        for (String withdrawalId:withdrawalList) {
//       数据
            WithdrawalResult withdrawalResult = queryWithdrawal(withdrawalId);
            String sheetName=withdrawalResult.getWithdrawalNo();
            HSSFSheet sheet=wb.createSheet(sheetName);
            // 设置打印页面
            ExcelStyle.printSetup(sheet);
            sheet.setDefaultColumnWidth(12);
            sheet.setColumnWidth(0,5*256);
            sheet.setColumnWidth(1,17*256);
            HSSFRow row_title = sheet.createRow(0);
            row_title.setHeight((short) (38 * 20));
            HSSFCell cell_title = row_title.createCell(1);
            cell_title.setCellValue(title);
            cell_title.setCellStyle(ExcelStyle.styleTitle(wb));
            row_title.setHeight((short)690);
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 1, 8)); // 合并单元格显示
            String[] cellName={ "退库单号：","退库日期：","处理人：",
                    "退库后使用公司：","退库后区域：",
                    "退库后存放地点：","退库备注："};
            String[] cellValue={ withdrawalResult.getWithdrawalNo(),withdrawalResult.getWithdrawalDate(),withdrawalResult.getHandlerUser(),
                    withdrawalResult.getWithdrawalCompany(),withdrawalResult.getWithdrawalArea(),
                    withdrawalResult.getWithdrawalAddress(),withdrawalResult.getWithdrawalRemark()};
            AtomicInteger cellCount = new AtomicInteger();
            AtomicInteger valCount = new AtomicInteger();
            for (int i = 1; i < 5 ; i++) {
                HSSFRow row = sheet.createRow(i);
                for(int c = 1 ;c< 9; c++){
                    HSSFCell cell = row.createCell(c);
                    if(c%3==0 || (i==3&&c>2) ||(i==4&&c>2) ||(i==2 && c > 5)){
                        cell.setCellValue("");
                        cell.setCellStyle(ExcelStyle.styleNotBorder(wb,0));
                        continue;
                    }
                    if(c%3==1){
                        cell.setCellValue(cellName[cellCount.getAndIncrement()]);
                        cell.setCellStyle(ExcelStyle.styleNotBorder(wb,0));
                        continue;
                    }

                    cell.setCellValue(cellValue[valCount.getAndIncrement()]);
                    cell.setCellStyle(ExcelStyle.styleNotBorder(wb,0));
                }
            }
            // 设置边框
            CellRangeAddress cell1 = new CellRangeAddress(1, 1, 2, 3);
            CellRangeAddress cell2 = new CellRangeAddress(2, 2, 5, 8);// 合并单元格显示
            CellRangeAddress cell22 = new CellRangeAddress(2, 2, 2, 3);
            CellRangeAddress cell3 = new CellRangeAddress(3, 3, 2, 8);// 合并单元格显示
            CellRangeAddress cell4 = new CellRangeAddress(4, 4, 2, 8);// 合并单元格显示
            sheet.addMergedRegion(cell1);
            sheet.addMergedRegion(cell2);
            sheet.addMergedRegion(cell22);
            sheet.addMergedRegion(cell3);
            sheet.addMergedRegion(cell4);

            HSSFRow row = sheet.createRow(5);
            row.setHeight((short)600);
            HSSFCell cell = row.createCell(1);
            cell.setCellValue("资产明细：");
            cell.setCellStyle(ExcelStyle.styleNotBorder(wb,1));

            String[] colName={"序号","资产条码","资产类别","资产名称",
                    "规格型号","SN号","金额","管理员"};
            row = sheet.createRow(6);
            AtomicInteger colNum = new AtomicInteger();
            for (int i = 1; i <9; i++) {
                cell = row.createCell(i);
                cell.setCellValue(colName[colNum.getAndIncrement()]);
                cell.setCellStyle(ExcelStyle.styleCellName(wb));
            }
            List<WarehouseHistoryResult> warehouseList = withdrawalResult.getWarehouseList();
            AtomicInteger rowNum = new AtomicInteger(7);
            AtomicInteger numNo = new AtomicInteger(1);
            if(warehouseList!=null) {
                for (int i = 0; i < warehouseList.size(); i++) {
                    WarehouseHistoryResult warehouseResult = warehouseList.get(i);
                    String[] colValue = {warehouseResult.getAssetCode(), warehouseResult.getAssetClassName(),
                            warehouseResult.getAssetName(), warehouseResult.getSpecificationModel(),
                            warehouseResult.getSnNumber(), warehouseResult.getAmount(), warehouseResult.getAdmin()};
                    row = sheet.createRow(rowNum.getAndIncrement());
                    // 序号
                    cell = row.createCell(1);
                    cell.setCellValue(i + 1);
                    cell.setCellStyle(ExcelStyle.styleCellValue(wb));
                    // 数据
                    AtomicInteger cellNum = new AtomicInteger(0);
                    for (int j = 2; j < 9; j++) {
                        cell = row.createCell(j);
                        String str = colValue[cellNum.getAndIncrement()];
                        cell.setCellValue(str);
                        cell.setCellStyle(ExcelStyle.styleCellValue(wb));
                    }
                }
            }
            // 页尾
            row = sheet.createRow(rowNum.getAndIncrement());
            cell = row.createCell(1);
            cell.setCellValue("退库人签字：");
            cell.setCellStyle(ExcelStyle.styleNotBorder(wb,0));

            cell = row.createCell(7);
            cell.setCellValue("签字时间：");
            cell.setCellStyle(ExcelStyle.styleNotBorder(wb,0));
        }
        return wb;
    }

    public Integer updateSign(SignatureParam param) {
        String token = request.getHeader("token");
        LoginUser user = cacheUtils.getUser(token);
        String userId = user.getUserId();

        WithdrawalParam withdrawal = new WithdrawalParam();
        withdrawal.setWithdrawalId(param.getId());
        withdrawal.setSignPic(param.getSignPic());
        withdrawal.setState(2); // 已签字
        withdrawal.setUpdateTime(DateTools.nowDate());
        withdrawal.setUpdateUser(userId);
        int i = mapper.updateByPrimaryKeySelective(withdrawal);

        // 修改审批单的状态为签字 4
        Withdrawal apply = mapper.selectByPrimaryKey(withdrawal.getWithdrawalId());
        if(StringUtils.isNotEmpty(apply.getApplyId())){
            AssetWithdrawal awApply = new AssetWithdrawal();
            awApply.setId(apply.getApplyId());
            awApply.setState(4);
            awApply.setUpdateDate(DateTools.nowDate());
            awApply.setUpdateUser(userId);
            assetWithdrawalMapper.updateByPrimaryKeySelective(awApply);
        }

        WithdrawalResult withdrawalResult = queryWithdrawal(param.getId());
        List<String> assetIdList = withdrawalResult.getWarehouseList().stream().map(e -> e.getAssetId()).collect(Collectors.toList());
        //修改资产状为闲置
        Warehouse warehouse = new Warehouse();
        warehouse.setState("闲置");
        warehouse.setUseCompany(withdrawalResult.getWithdrawalCompany());
        warehouse.setUseCompanyTreecode(withdrawalResult.getWithdrawalCompanyTreecode());
        warehouse.setUseDepartment("");
        warehouse.setUseDeptTreecode("");
        warehouse.setArea(withdrawalResult.getWithdrawalArea());
        warehouse.setStorageLocation(withdrawalResult.getWithdrawalAddress());
        warehouse.setHandlerUser("");
        warehouse.setHandlerUserId("");
        warehouseService.updateAsset(assetIdList, warehouse);
        insertLog2(assetIdList, param.getId());
        return i;
    }

    public Integer insertWithdrawalApply(WithdrawalApplyParam withdrawal) {

        //--------- 权限 start
        String token = request.getHeader("token");
        // redis 查询用户权限： 如果是管理员为false 查询全部
        LoginUser loginUser = cacheUtils.getUser(token);
        String userId = loginUser.getUserId();
        List<CompanyBaseListResult> companys = loginUser.getCompanys();
        String orgId = companys.get(0).getCompanyId();
        Long increment = redisUtil.getIncr("RVT_"+orgId+"_"+DateTools.nowDayStr(),DateTools.expiresTime());
        String no = String.format("%04d",Long.valueOf(increment));

        withdrawal.setWithdrawalNo("RVT"+DateTools.nowDayStr()+no);
        withdrawal.setApproval(1); // 待发放
        withdrawal.setWithdrawalType(1); // 员工申请
        withdrawal.setState(1); // 未签字
        withdrawal.setWithdrawalUserId(userId);
        withdrawal.setOrgId(orgId);
        if(withdrawal.getWithdrawalDate()==null){
            withdrawal.setWithdrawalDate(DateTools.nowDay());
        }

        withdrawal.setCreateTime(DateTools.nowDate());
        withdrawal.setCreateUser(userId);
        withdrawal.setUpdateTime(DateTools.nowDate());
        withdrawal.setUpdateUser(userId);
        withdrawal.setIsDelete(0);
        int i = mapper.insertSelective(withdrawal);

        Set<String> adminIds =  new HashSet<>();

        for (AssetWithdrawal assetWithdrawal : withdrawal.getAssetWithdrawalList()) {
            assetWithdrawal.setWithdrawalId(withdrawal.getWithdrawalId());
            assetWithdrawal.setIsDeleted(0);
            if(assetWithdrawal.getType()==null){
                assetWithdrawal.setType(1);
            }
            if(assetWithdrawal.getAssetNum()==null){
                assetWithdrawal.setAssetNum(1);
            }
            assetWithdrawal.setState(1);
            assetWithdrawal.setCreateUser(userId);
            assetWithdrawal.setCreateDate(TimeTool.getCurrentTimeStr());
            assetWithdrawal.setUpdateUser(userId);
            assetWithdrawal.setUpdateDate(TimeTool.getCurrentTimeStr());
            assetWithdrawalMapper.insertSelective(assetWithdrawal);

            //给指定分类或资产管理员推送消息
//            if(assetWithdrawal.getType() == 1){
                //获取资产信息
//                WarehouseResult info = warehouseService.queryByAssetId(assetWithdrawal.getAssetId());
//                String[] asia = {info.getAdmin()};
//                String notification_title = "退库申请";
//                String msg_title = "退库申请";
//                String msg_content = "资产编号：" + info.getAssetCode() +" 退库申请";
//                log.info("退库申请,消息推送人："+ JSONObject.toJSONString(asia));
//                JpushClientUtil.sendToAsia(asia, notification_title, msg_title, msg_content,"");
//            }
//            if(assetWithdrawal.getType() == 2){
                //通过资产标准类型获取资产分类管理人员
//                String[] asia = setService.getUserIdByModelId(Arrays.asList(assetWithdrawal.getAssetId().split(",")));
//                StandModelEntity entity = setService.selStandModelById(assetWithdrawal.getAssetId());
//                String notification_title = "退库申请";
//                String msg_title = "退库申请";
//                String msg_content = "资产标准型号：" + entity.getModel() + ",数量：" + assetWithdrawal.getAssetNum() +" 退库申请";
//                log.info("退库申请,消息推送人："+ JSONObject.toJSONString(asia));
//                JpushClientUtil.sendToAsia(asia, notification_title, msg_title, msg_content,"");
//            }
            List<String> adminIdList = mapper.getModelOrAssetAdmin(orgId, assetWithdrawal.getAssetId(), assetWithdrawal.getType());
            if(!CollectionUtils.isEmpty(adminIdList)){
                adminIds.addAll(adminIdList);
            }
        }
        Warehouse warehouse = new Warehouse();
        warehouse.setState("退库中");
        List<String> assetIdList = withdrawal.getAssetWithdrawalList().stream().map(e ->
             e.getAssetId()
        ).collect(Collectors.toList());
        warehouseService.updateAsset(assetIdList, warehouse);
        // 添加退库申请记录
        addApplyLog(assetIdList,withdrawal.getWithdrawalId());
        String[] asia = adminIds.toArray(new String[adminIds.size()]);
        String notification_title = "退库资产申请";
        String msg_title = "退库资产申请";
        String msg_content = "退库资产申请，单号【"+ withdrawal.getWithdrawalNo() +"】";
        log.info("退库资产申请,消息推送人："+ JSONObject.toJSONString(asia));
        JpushClientUtil.sendToAsia(asia, notification_title, msg_title, msg_content,"");

        String finalMsg_content = msg_content;
        Arrays.stream(asia).forEach(e->{
            PushManagement pu = new PushManagement();
            pu.setCompanyId(orgId);
            pu.setContent(finalMsg_content);
            pu.setCtime(DateTools.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
            pu.setCuser(userId);
            pu.setSender(e);
            pu.setResult(0);
            pushMapper.insertSelective(pu);
        });

        return i;
    }

    private void addApplyLog(List<String> assetIdList, String handlerId) {
        //--------- 权限 start
        String token = request.getHeader("token");
        LoginUser loginUser = cacheUtils.getUser(token);
        String userId = loginUser.getUserId();
        String userName = loginUser.getUserName();

        for (String assetId:assetIdList) {
            AssetLog assetLog = new AssetLog();
            assetLog.setCreateTime(DateTools.nowDate());
            assetLog.setCreateUser(userId);
            assetLog.setUpdateTime(DateTools.nowDate());
            assetLog.setUpdateUser(userId);
            assetLog.setLogType("退库");
            assetLog.setAssetId(assetId);
            assetLog.setHandlerId(handlerId);
            assetLog.setHandlerUser(userName);
            assetLog.setHandlerContext("员工" + userName + "将提起退库申请");
            assetLogMapper.insertSelective(assetLog);
        }
    }

    public Integer withdrawalApplyAgree(WithdrawalApplyAgreeParam param) {
        String token = request.getHeader("token");
        // redis 查询用户权限： 如果是管理员为false 查询全部
        LoginUser loginUser = cacheUtils.getUser(token);
        String userId = loginUser.getUserId();
        String username = loginUser.getUserName();
        AssetWithdrawal aw =  new AssetWithdrawal();
        aw.setId(param.getId());
        aw.setState(2);
        aw.setUpdateDate(DateTools.nowDate());
        aw.setUpdateUser(userId);
        assetWithdrawalMapper.updateByPrimaryKeySelective(aw);
//        String withdrawalId = param.getWithdrawalId();

        // 修改总单状态   同意  2
//        updateApply(withdrawalId,2);

        AssetWithdrawal assetWithdrawal = assetWithdrawalMapper.selectByPrimaryKey(param.getId());
        WithdrawalParam withdrawal = new WithdrawalParam();
        withdrawal.setHandlerUser(username);
        withdrawal.setWithdrawalDate(DateTools.nowDay());
        withdrawal.setAssetIdList(param.getAssetIdList());
        withdrawal.setApplyId(param.getId());
        withdrawal.setWithdrawalUserId(assetWithdrawal.getCreateUser()); // 退库使用人
        //管理员发放
        Integer  i = insertWithdrawal(withdrawal);
        return i;
    }

//    private void updateApply(String withdrawalId, Integer state) {
//        Example example = new Example(AssetWithdrawal.class);
//        Example.Criteria criteria = example.createCriteria();
//        criteria.andEqualTo("withdrawalId",withdrawalId);
//        criteria.andEqualTo("state",1);
//        List<AssetWithdrawal> assetWithdrawals = assetWithdrawalMapper.selectByExample(example);
//        if(assetWithdrawals!=null && assetWithdrawals.size()>0){
//            return;
//        }
//        Withdrawal withdrawal = mapper.selectByPrimaryKey(withdrawalId);
//
//        String token = request.getHeader("token");
//        LoginUser loginUser = cacheUtils.getUser(token);
//        String userId = loginUser.getUserId();
//
//        Withdrawal withdrawalApply = new Withdrawal();
//        if(withdrawal.getState()!=2){
//            withdrawalApply.setApproval(state);
//        }
//        withdrawalApply.setWithdrawalId(withdrawalId);
//        withdrawalApply.setUpdateTime(DateTools.nowDate());
//        withdrawalApply.setUpdateUser(userId);
//        mapper.updateByPrimaryKeySelective(withdrawalApply);
//    }

    public Integer withdrawalApplyRefuse(WithdrawalApplyAgreeParam param) {
        String token = request.getHeader("token");
        LoginUser loginUser = cacheUtils.getUser(token);
        String userId = loginUser.getUserId();

//        AssetReceive ar =  assetReceiveMapper.selectByPrimaryKey(collect.getId());
        AssetWithdrawal aw = new AssetWithdrawal();
        aw.setId(param.getId());
        aw.setState(3);
        aw.setUpdateDate(DateTools.nowDate());
        aw.setUpdateUser(userId);
        int i = assetWithdrawalMapper.updateByPrimaryKeySelective(aw);

//        驳回为 3
//        updateApply(param.getWithdrawalId(),3);

        Warehouse warehouse = new Warehouse();
        warehouse.setState("在用");
        List<String> assetIdList = param.getAssetIdList();
        warehouseService.updateAsset(assetIdList, warehouse);
        return i;
    }

    public List<WithdrawalApplyResult> getAllWithdrawalApply(ApplySelParam params){
        String token = request.getHeader("token");
        String userId = cacheUtils.getUserId(token);
        String date = params.getSelTimeType();
        if("1".equals(date)){
            date = getTime(-1);
        } else if("2".equals(date))  {
            date = getTime(-3);
        } else if("3".equals(date))  {
            date = getTime(-6);
        } else {
            throw new LogicException("查询时间不正确");
        }
        Integer state = params.getState();
        List<WithdrawalApplyResult> list = mapper.getAllWithdrawalApply(date, userId, state);

        if(list != null && list.size()>0 ){
            for (WithdrawalApplyResult apply : list) {
                //申请明细
                List<AssetWithdrawalApply> applyList = new ArrayList<>();
                //发放明细
                List<WithdrawalResult> resultList = new ArrayList<>();

                // 查询子单符合状态的数据
                Example example = new Example(AssetWithdrawal.class);
                Example.Criteria criteria = example.createCriteria();
//                审批状态
                criteria.andEqualTo("state", state);
                criteria.andEqualTo("withdrawalId", apply.getWithdrawalId());
                List<AssetWithdrawal> assetReceiveList = assetWithdrawalMapper.selectByExample(example);
                if(assetReceiveList != null && assetReceiveList.size() > 0){
                    for (AssetWithdrawal assetWithdrawal : assetReceiveList) {

                        AssetWithdrawalApply assetWithdrawalApply = new AssetWithdrawalApply();
                        BeanUtils.copyProperties(assetWithdrawal,assetWithdrawalApply);
                        if(assetWithdrawal.getType() == 1){
                            Warehouse warehouse = warehouseMapper.selectByPrimaryKey(assetWithdrawal.getAssetId());
                            assetWithdrawalApply.setAssetCode(warehouse.getAssetCode());
                            assetWithdrawalApply.setAssetName(warehouse.getAssetName());
                            assetWithdrawalApply.setUnitMeasurement(warehouse.getUnitMeasurement());
                        } else if(assetWithdrawal.getType() == 2){
                            StandModel model = standModelMapper.selectByPrimaryKey(assetWithdrawal.getAssetId());
                            assetWithdrawalApply.setAssetModel(model.getModel());
                            assetWithdrawalApply.setAssetName(model.getName());
                            assetWithdrawalApply.setUnitMeasurement(model.getType());
                        }
                        applyList.add(assetWithdrawalApply);

                        //申请已审批发放明细
                        if(assetWithdrawal.getState() == 2){ // 已审批
                            Example example2 = new Example(Collect.class);
                            Example.Criteria criteria2 = example2.createCriteria();
                            criteria2.andEqualTo("applyId", assetWithdrawal.getId());
                            criteria2.andEqualTo("state", 1);
                            Withdrawal withdrawal = mapper.selectOneByExample(example2);
                            if(withdrawal!=null){
                                WithdrawalResult result = queryWithdrawal(withdrawal.getWithdrawalId());
                                resultList.add(result);
                            }
                        }
                        if(assetWithdrawal.getState() == 4){ // 已签字
                            Example example2 = new Example(Collect.class);
                            Example.Criteria criteria2 = example2.createCriteria();
                            criteria2.andEqualTo("applyId", assetWithdrawal.getId());
                            criteria2.andEqualTo("state", 2);
                            Withdrawal withdrawal = mapper.selectOneByExample(example2);
                            if(withdrawal!=null){
                                WithdrawalResult result = queryWithdrawal(withdrawal.getWithdrawalId());
                                resultList.add(result);
                            }
                        }
                    }
                }
                // 申请
                apply.setApplylist(applyList);
                // 发放
                apply.setResultList(resultList);
            }
        }
        return list;
    }

    /**
     * 获取几月之前的时间
     * @param num
     * @return
     */
    private String getTime(int num){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.MONTH, num);
        Date m = c.getTime();
        return format.format(m);
    }
    public WithdrawalApplyResult getWithdrawalApplyById(String id,Integer state){
        String token = request.getHeader("token");
        String userId = cacheUtils.getUserId(token);
//   如果是2  就是已审批待签字   4 就是已审批已签字
//        Integer state = 4;

        WithdrawalApplyResult applyResult = mapper.getWithdrawalApplyById(id, state);

        //申请明细
        List<AssetWithdrawalApply> applyList = new ArrayList<>();
        //发放明细
        List<WithdrawalResult> resultList = new ArrayList<>();

        // 查询子单符合状态的数据
        Example example = new Example(AssetWithdrawal.class);
        Example.Criteria criteria = example.createCriteria();
//                审批状态
        criteria.andEqualTo("state", state);
        criteria.andEqualTo("withdrawalId", applyResult.getWithdrawalId());
        List<AssetWithdrawal> assetReceiveList = assetWithdrawalMapper.selectByExample(example);
        if(assetReceiveList != null && assetReceiveList.size() > 0){
            for (AssetWithdrawal assetWithdrawal : assetReceiveList) {

                AssetWithdrawalApply assetWithdrawalApply = new AssetWithdrawalApply();
                BeanUtils.copyProperties(assetWithdrawal,assetWithdrawalApply);
                if(assetWithdrawal.getType() == 1){
                    Warehouse warehouse = warehouseMapper.selectByPrimaryKey(assetWithdrawal.getAssetId());
                    assetWithdrawalApply.setAssetCode(warehouse.getAssetCode());
                    assetWithdrawalApply.setAssetName(warehouse.getAssetName());
                    assetWithdrawalApply.setUnitMeasurement(warehouse.getUnitMeasurement());
                    assetWithdrawalApply.setType(1);
                } else if(assetWithdrawal.getType() == 2){
                    StandModel model = standModelMapper.selectByPrimaryKey(assetWithdrawal.getAssetId());
                    assetWithdrawalApply.setAssetName(model.getName());
                    assetWithdrawalApply.setAssetModel(model.getModel());
                    assetWithdrawalApply.setUnitMeasurement(model.getType());
                    assetWithdrawalApply.setUnitMeasurement(model.getType() == null ? "": model.getType());
                    assetWithdrawalApply.setAssetNum(assetWithdrawal.getAssetNum());
                    assetWithdrawalApply.setType(2);
                }
                applyList.add(assetWithdrawalApply);

                //申请已审批发放明细
                if(assetWithdrawal.getState() == 2){ // 已审批
                    Example example2 = new Example(Collect.class);
                    Example.Criteria criteria2 = example2.createCriteria();
                    criteria2.andEqualTo("applyId", assetWithdrawal.getId());
                    Withdrawal withdrawal = mapper.selectOneByExample(example2);
                    if(withdrawal!=null){
                        WithdrawalResult result = queryWithdrawal(withdrawal.getWithdrawalId());
                        resultList.add(result);
                    }
                }
                if(assetWithdrawal.getState() == 4){ // 已签字
                    Example example2 = new Example(Collect.class);
                    Example.Criteria criteria2 = example2.createCriteria();
                    criteria2.andEqualTo("applyId", assetWithdrawal.getId());
                    criteria2.andEqualTo("state", 2);
                    Withdrawal withdrawal = mapper.selectOneByExample(example2);
                    if(withdrawal!=null){
                        WithdrawalResult result = queryWithdrawal(withdrawal.getWithdrawalId());
                        resultList.add(result);
                    }
                }
            }
        }
        // 申请
        applyResult.setApplylist(applyList);
        // 发放
        applyResult.setResultList(resultList);
        return applyResult;
    }
}
